package com.zjl.redis.old.Redis6;

/**
 * Redis最大占用内存
 * redis.conf//配置文件中
 *      maxmemory <bytes>//设置最大内存 单位是字节 1G=1021Mb  1mb=1024字节
 *      如果不设置最大内存大小或者设置最大内存大小为0，
 *          在64位操作系统下不限制内存大小，在32位操作系统下最多使用3GB内存
 *      一般推荐Redis设置内存为最大物理内存的   四分之三
 * config get maxmemory//查看配置文件中maxmemory的值
 * config set maxmemory 大小//设置配置文件中maxmemory的值
 *
 * info//查看当前redis的所有所有信息
 * info memory//查看当前redis内存使用信息
 *
 */

/**
 * redis内存满了咋办
 * OOM异常//
 *
 * 如果一个键是过期的，那它到了过期时间之后是不是马上就从内存中被被删除呢? ?
 *    不是
 *    立即删除能保证内存中数据的最大新鲜度，因为它保证过期键值会在过期后马上被删除，
 *    其所占用的内存也会随之释放。但是立即删除对cpu是最不友好的
 *    因为删除操作会占用cpu的时间，如果刚好碰上了cpu很忙的时候，
 *    比如正在做交集或排序等计算的时候，就会给cpu造成额外的压力，
 *    让CPU心累，时时需要删除，忙死。。。。。。。
 *
 *    """这会产生大量的性能消耗，同时也会影响数据的读取操作。"""
 *   有下列三种删除方式
 *   1.定时删除
 *   2.惰性删除：//从来没有被点中使用过
 *       惰性删除策略的缺点是，它对内存是最不友好的。
 *       数据到达过期时间，不做处理。等下次访问该数据时,.
 *      如果未过期，返回数据     发现已过期，删除，返回不存在。
 *      在使用惰性删除策略时，如果数据库中有非常多的过期键，
 *      而这些过期键又恰好没有被访问到的话，那么它们也许永远也不会被删除
 *      (除非用户手动执行FLUSHDB)，
 *      我们甚至可以将这种情况看作是一种内存泄漏-无用的垃圾数据占用了大量的内存，
 *      而服务器却不会:自己去释放它们，
 *      这对运行状态非常依赖于内存的Redis服务器来说,肯定不是一个好消息
 *   3.定期删除//定期删除时，从来没有被抽查到
 *      定期删除策略每隔一段时间执行一次删除过期键操作，//随机抽样删除(可能会出现  过期的键一直抽查不到)
 *      并通过限制删除操作执行的时长和频率来减少删除操作对CPU时间的影响。
 *
 * 2  3  还是会有可能有大量的key堆积在内存中导致redis空间紧张
 */

import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Set;

/**
 * redis内存淘汰策略
 * 定期删除和惰性删除 会有可能有大量的key堆积在内存中导致redis空间紧张
 * 引出了   redis内存淘汰策略
 * redis.conf//配置文件中
 *
 * maxmemory-policy
 * 一旦到达内存使用上限, redis 将会试图移除内部数据,移除规则
 * # ➢volatile-lru :使用LRU算法移除key,只对设置了过期时间的键; (最近最少使用)。
 * # ➢allkeys-lru :在所有集合key中,使佣LRU算法移除key.//最近最少使用   一般公司动用这个
 * # ➢volatile-random :在过期集合中移除随机的key ,只对设置了过期时间的键。
 * # ➢allkeys-random :在所有集合key中,移除随机的keys
 * # ➢volatie-tt :移除那些TL值最小的key ,即那些最近要过期的key.
 * # ➢noeviction :不进行移除。针对写操作,只是返回错误信息
 * # maxmemory-policy noeviction
 *
 */
public class Redis内存管理 {
    public static void main(String[] args) {
        /**
         * map遍历
         */
        LinkedHashMap<Integer,Integer> map = new LinkedHashMap<>();
        Set<Map.Entry<Integer, Integer>> entries = map.entrySet();
        for(Map.Entry<Integer,Integer> e:entries){
            e.getKey();
            e.getValue();
        }

    }
}
class LRU<K,V> extends LinkedHashMap<K,V>{
    private int initialCapacity;
    public LRU(int initialCapacity) {
        super(initialCapacity,0.75f,true);
        //     链表数量            负载因子          当加入重复元素时位置改变
        //如true: put(1,1)  put(2,1)  put(3,1)    put(2,2)    sout(1=1,3=1,2=2)
        //false : put(1,1)  put(2,1)  put(3,1)    put(2,2)    sout(1=1,2=2,3=1)
        this.initialCapacity=initialCapacity;
    }
    @Override
    protected boolean removeEldestEntry(Map.Entry<K,V> eldest) {
        return super.size()>initialCapacity;
    }

}
